package com.zbkj.crmeb.statistics.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.constants.Constants;
import com.constants.WeChatConstants;
import com.utils.CrmebUtil;
import com.utils.DateUtil;
import com.crmeb.core.utils.RedisUtil;
import com.utils.vo.dateLimitUtilVo;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.crmeb.core.config.RestTemplateConfig;
import com.zbkj.crmeb.enums.CurrencyEnum;
import com.zbkj.crmeb.statistics.response.*;
import com.zbkj.crmeb.statistics.service.HomeService;
import com.zbkj.crmeb.store.model.PurchaseGoods;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.model.StoreOrderInfo;
import com.zbkj.crmeb.store.model.StoreProductAttrValue;
import com.zbkj.crmeb.store.response.StoreCartResponse;
import com.zbkj.crmeb.store.response.SupplierInfo;
import com.zbkj.crmeb.store.service.PurchaseGoodsService;
import com.zbkj.crmeb.store.service.StoreOrderInfoService;
import com.zbkj.crmeb.store.service.StoreOrderService;
import com.zbkj.crmeb.system.service.SystemConfigService;
import com.zbkj.crmeb.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author Mr.Zhang
 * @since 2020-05-16
 */
@Service
@Slf4j
public class HomeServiceImpl implements HomeService {

    @Autowired
    private StoreOrderService storeOrderService;

    @Autowired
    private UserService userService;

    @Autowired
    private StoreOrderInfoService storeOrderInfoService;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private IChannelMerchantService channelMerchantService;

    @Autowired
    RestTemplateConfig restTemplateConfig;

    @Autowired
    RedisUtil redisUtil;
    @Autowired
    private PurchaseGoodsService purchaseGoodsService;

    @Value("${server.wechatProgramToken}")
    private Boolean programTokenFlag;
    /**
     * 销售额
     * @author Mr.Zhang
     * @since 2020-05-16
     * @return HashMap<String, Object>
     */
    @Override
    public HomeRateResponse sales(List<Integer> merIds) {
//        BigDecimal today = storeOrderService.getSumBigDecimal(null, Constants.SEARCH_DATE_DAY);
//        BigDecimal yesterday = storeOrderService.getSumBigDecimal(null, Constants.SEARCH_DATE_YESTERDAY);
//        //本周销售额
//        BigDecimal week = storeOrderService.getSumBigDecimal(null, Constants.SEARCH_DATE_WEEK);
//        //上周销售额
//        BigDecimal preWeek = storeOrderService.getSumBigDecimal(null, Constants.SEARCH_DATE_PRE_WEEK);
//        BigDecimal all = storeOrderService.getSumBigDecimal(null, null);
//        int dayRate = CrmebUtil.getRate(today, yesterday);
//        //周同比
//        int weekRate = CrmebUtil.getRate(week, preWeek);

//        //今日销售额
//        BigDecimal today = storeOrderInfoService.getSumBigDecimal(Constants.SEARCH_DATE_DAY, merId);
//        //昨天销售额
//        BigDecimal yesterday = storeOrderInfoService.getSumBigDecimal(Constants.SEARCH_DATE_YESTERDAY, merId);
//        //总销售额
//        BigDecimal all = storeOrderInfoService.getSumBigDecimal(null, merId);
//        // 日同比 同比公式 即：同比增长率=（本年的指标值-去年同期的值）/ 去年同期的值 * 100%
//        BigDecimal dayRate = CrmebUtil.getRateDecimal(today, yesterday);

        // 今天
        BigDecimal today = storeOrderInfoService.getSumBigDecimalByMerIds(Constants.SEARCH_DATE_DAY,merIds);
        // 昨天
        BigDecimal yesterday = storeOrderInfoService.getSumBigDecimalByMerIds(Constants.SEARCH_DATE_YESTERDAY,merIds);
        // 全部
        BigDecimal all = storeOrderInfoService.getSumBigDecimalByMerIds(null,merIds);
        BigDecimal dayRate = CrmebUtil.getRateDecimal(today, yesterday);
        return new HomeRateResponse(today, yesterday, dayRate + "%", null, all);
    }

    /**
     * 订单量
     * @author Mr.Zhang
     * @since 2020-05-16
     * @return HashMap<String, Object>
     */
    @Override
    public HomeRateResponse order(List<Integer> merIds) {

        ///今日数量
//        int today = storeOrderService.getOrderCount(null, Constants.SEARCH_DATE_DAY);
//        int todayChild =storeOrderInfoService.getChildOrderCount(Constants.SEARCH_DATE_DAY,merId);

        //昨日数量
//        int yesterday = storeOrderService.getOrderCount(null, Constants.SEARCH_DATE_YESTERDAY);
//        int yesterdayChild =storeOrderInfoService.getChildOrderCount(Constants.SEARCH_DATE_YESTERDAY,merId);
//
//        //本周数量
//        int week = storeOrderService.getOrderCount(null, Constants.SEARCH_DATE_WEEK);
//
//        //上周数量
//        int preWeek = storeOrderService.getOrderCount(null, Constants.SEARCH_DATE_PRE_WEEK);

        //总数量
//        int all = storeOrderInfoService.getChildOrderCount(null,merId);

        //同比公式 即：同比增长率=（本年的指标值-去年同期的值）/ 去年同期的值 * 100%

        //日同比
//        int dayRate = CrmebUtil.getRate(today, yesterday);
//        BigDecimal dayRateDecimal = CrmebUtil.getRateDecimal(todayChild, yesterdayChild);

        //周同比
//        int weekRate = CrmebUtil.getRate(week, preWeek);

        ///今日数量
        int todayChild = storeOrderInfoService.countChildOrderByMerIds(Constants.SEARCH_DATE_DAY, merIds);
        //昨日数量
        int yesterdayChild = storeOrderInfoService.countChildOrderByMerIds(Constants.SEARCH_DATE_YESTERDAY, merIds);
        //总数量
        int all = storeOrderInfoService.countChildOrderByMerIds(null, merIds);
        //日同比
        BigDecimal dayRateDecimal = CrmebUtil.getRateDecimal(todayChild, yesterdayChild);
        return new HomeRateResponse(todayChild, yesterdayChild, dayRateDecimal + "%", null, all);
    }

    /**
     * 新增用户
     * @author Mr.Zhang
     * @since 2020-07-30
     * @return UserCreateResponse
     */
    @Override
    public HomeRateResponse user(List<Integer> merIds) {
        //今日数量
        Integer today = userService.getAddUserCountByDate(Constants.SEARCH_DATE_DAY,merIds);

        //昨日数量
        Integer yesterday = userService.getAddUserCountByDate(Constants.SEARCH_DATE_YESTERDAY,merIds);

//        //本周数量
//        Integer week = userService.getAddUserCountByDate(Constants.SEARCH_DATE_WEEK);
//
//        //上周数量
//        Integer preWeek = userService.getAddUserCountByDate(Constants.SEARCH_DATE_PRE_WEEK);

        //总数量
        Integer all = userService.getAddUserCountByDate(null,merIds);

        //同比公式 即：同比增长率=（本年的指标值-去年同期的值）/ 去年同期的值 * 100%

        //日同比
//        int dayRate = CrmebUtil.getRate(today, yesterday);
        BigDecimal dayRateDecimal = CrmebUtil.getRateDecimal(today, yesterday);

        //周同比
//        int weekRate = CrmebUtil.getRate(week, preWeek);

        return new HomeRateResponse(today,yesterday, dayRateDecimal+"%", null, all);
    }

    /**
     * 用户访问量
     * @author Mr.Zhang
     * @since 2020-05-16
     * @return HashMap<String, Object>
     */
    @Override
    public HomeRateResponse views(List<Integer> merId) {
        //昨日
        int yesterday = 0;
        //前天
        int beforeYesterday = 0;
        //总数
        int all = 0;

        if (!programTokenFlag) {
            return new HomeRateResponse(yesterday,beforeYesterday, BigDecimal.ZERO+"%", null, all);
        }
        //商户权限为SaaS且未删除的，才进行浏览量查询
        List<ChannelMerchant> channelMerchantList = channelMerchantService.list(Wrappers.lambdaQuery(ChannelMerchant.class)
                .eq(ChannelMerchant::getChannelType, 2)
                .eq(ChannelMerchant::getIsDel, 0)
                .in(CollectionUtils.isNotEmpty(merId), ChannelMerchant::getId, merId));
        for (ChannelMerchant channelMerchant : channelMerchantList) {
            log.info("-----------获取小程序访问量,商户id:{}-----------",channelMerchant.getId());
            try{
                String accessToken = (String) redisUtil.get(WeChatConstants.REDIS_PROGRAM_TOKEN_KEY + "_" + channelMerchant.getId());
                if(StringUtils.isBlank(accessToken)){
                    String appId = systemConfigService.getValueByKey("routine_appid_" + channelMerchant.getId());
                    String secret = systemConfigService.getValueByKey("routine_appsecret_" + channelMerchant.getId());
                    if(StringUtils.isNotBlank(appId) && StringUtils.isNotBlank(secret)){
                        JSONObject jsonObject = getAccessToken(appId, secret);
                        if(jsonObject == null){
                            continue;
                        }
                        accessToken = jsonObject.get("access_token").toString();
                        long expires = Long.parseLong(jsonObject.getString("expires_in"));
                        redisUtil.set(WeChatConstants.REDIS_PROGRAM_TOKEN_KEY + "_" + channelMerchant.getId(), accessToken, expires -100, TimeUnit.SECONDS);
                    }else {
                        log.info("-----------获取小程序访问量失败,商户appid或appsecret不存在,商户id:{} -----------",channelMerchant.getId());
                        continue;
                    }
                }
                Object yesterdayCount = redisUtil.get(StrUtil.format(Constants.APPLET_VISIT_PV, channelMerchant.getId(), DateUtil.getDaysAgo(1)));
                if(Objects.isNull(yesterdayCount)){
                    Integer dailyVisitTrend = getDailyVisitTrend(accessToken, DateUtil.getDaysAgo(1));
                    if(Objects.nonNull(dailyVisitTrend)){
                        yesterday += dailyVisitTrend;
                        redisUtil.set(StrUtil.format(Constants.APPLET_VISIT_PV, channelMerchant.getId(),DateUtil.getDaysAgo(1)),yesterday,30L,TimeUnit.DAYS);
                    }else {
                        //失败一次 跳出
                        continue;
                    }
                }else {
                    yesterday += (int) yesterdayCount;
                }
                Object beforeYesterdayCount = redisUtil.get(StrUtil.format(Constants.APPLET_VISIT_PV, channelMerchant.getId(), DateUtil.getDaysAgo(2)));
                if(Objects.isNull(beforeYesterdayCount)){
                    Integer dailyVisitTrend = getDailyVisitTrend(accessToken, DateUtil.getDaysAgo(2));
                    if(Objects.nonNull(dailyVisitTrend)){
                        beforeYesterday += dailyVisitTrend;
                        redisUtil.set(StrUtil.format(Constants.APPLET_VISIT_PV, channelMerchant.getId(),DateUtil.getDaysAgo(2)),beforeYesterday,30L,TimeUnit.DAYS);
                    }
                }else {
                    beforeYesterday += (Integer) beforeYesterdayCount;
                }
                //获得创建时间到当前日期上月yyyymmdd集合
                List<String> monthBetween = DateUtil.getMonthBetween(channelMerchant.getCreateTime(), new Date());
                for (String month : monthBetween) {
                    Object monthCount = redisUtil.get(StrUtil.format(Constants.APPLET_VISIT_PV, channelMerchant.getId(), month));
                    if(Objects.isNull(monthCount)){
                        Integer monthlyVisitTrend = getMonthlyVisitTrend(month.replace("-", "") + "01", DateUtil.getLastDayTimeOfMonth(month), accessToken);
                        if(Objects.nonNull(monthlyVisitTrend)){
                            all += monthlyVisitTrend;
                            redisUtil.set(StrUtil.format(Constants.APPLET_VISIT_PV, channelMerchant.getId(),month),monthlyVisitTrend,30L,TimeUnit.DAYS);
                        }
                    }else {
                        all += (int)monthCount;
                    }
                }
                List<String> dateBetween = DateUtil.getDateBetween(new Date());
                for (String date : dateBetween) {
                    Object dateCount = redisUtil.get(StrUtil.format(Constants.APPLET_VISIT_PV, channelMerchant.getId(), date));
                    if(Objects.isNull(dateCount)){
                        Integer dailyVisitTrend = getDailyVisitTrend(accessToken, date);
                        if(Objects.nonNull(dailyVisitTrend)){
                            all += dailyVisitTrend;
                            redisUtil.set(StrUtil.format(Constants.APPLET_VISIT_PV, channelMerchant.getId(), date),dailyVisitTrend,30L,TimeUnit.DAYS);
                        }
                    }else {
                        all += (int)dateCount;
                    }
                }
            }catch (Exception e){
                log.error("-----------获取小程序访问次数异常,商户id:{},msg:{}-----------",channelMerchant.getId(),e.getMessage());
            }
        }
        //日同比
        BigDecimal dayRateDecimal = CrmebUtil.getRateDecimal(yesterday, beforeYesterday);
        return new HomeRateResponse(yesterday,beforeYesterday, dayRateDecimal+"%", null, all);
    }

    /**
     * 小程序月趋势
     * @param startDate
     * @param endDate
     * @param accessToken
     * @return
     */
    private Integer getMonthlyVisitTrend(String startDate, String endDate,String accessToken) {
        try{
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("begin_date",startDate);
            jsonObject.put("end_date",endDate);
            HttpEntity<JSONObject> formEntity = new HttpEntity<>(jsonObject, null);
            RestTemplate restTemplate = restTemplateConfig.restTemplate();
            ResponseEntity<String> response = restTemplate.postForEntity("https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyvisittrend?access_token=" + accessToken, formEntity, String.class);
            DailyVisitTrendResponse dailyVisitTrendResponse = JSONObject.parseObject(response.getBody(), DailyVisitTrendResponse.class);
            if(dailyVisitTrendResponse == null || CollectionUtils.isEmpty(dailyVisitTrendResponse.getList())){
                log.info("-----------获取小程序月趋势失败,返回结果:{}-----------",response.getBody());
                return null;
            }
            return dailyVisitTrendResponse.getList().get(0).getVisitPv();
        }catch (Exception e){
            log.error("-----------获取小程序月趋势异常:{}-----------",e.getMessage());
        }
        return null;
    }

    /**
     * 小程序日趋势
     * @param accessToken
     * @param date
     * @return
     */
    private Integer getDailyVisitTrend(String accessToken, String date) {
        try{
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("begin_date",date);
            jsonObject.put("end_date",date);
            HttpEntity<JSONObject> formEntity = new HttpEntity<>(jsonObject, null);
            RestTemplate restTemplate = restTemplateConfig.restTemplate();
            ResponseEntity<String> response = restTemplate.postForEntity("https://api.weixin.qq.com/datacube/getweanalysisappiddailyvisittrend?access_token=" + accessToken, formEntity, String.class);
            DailyVisitTrendResponse dailyVisitTrendResponse = JSONObject.parseObject(response.getBody(), DailyVisitTrendResponse.class);
            if(dailyVisitTrendResponse == null || CollectionUtils.isEmpty(dailyVisitTrendResponse.getList())){
//                log.error("-----------获取小程序日趋势失败,返回结果:{}-----------",response.getBody());
                return null;
            }
            return dailyVisitTrendResponse.getList().get(0).getVisitPv();
        }catch (Exception e){
            log.error("-----------获取小程序日趋势异常1:{}-----------",e.getMessage());
        }
        return null;
    }

    /**
     * 获取access_token
     * @param appId
     * @param secret
     * @return
     */
    private JSONObject getAccessToken(String appId, String secret) {
        RestTemplate restTemplate = restTemplateConfig.restTemplate();
        ResponseEntity<String> response = restTemplate.getForEntity("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" + "&appid=" + appId + "&secret=" + secret, String.class);
        JSONObject jsonObject = JSONObject.parseObject(response.getBody());
        if(!jsonObject.containsKey("access_token")){
            log.error("-----------获取微信token失败,msg:{}-----------",jsonObject.getString("errmsg"));
            return null;
        }
        return  jsonObject;
    }

    /**
     * 用户曲线图
     *
     * @author Mr.Zhang
     * @since 2020-05-16
     */
    @Override
    public Map<Object, Object> chartUser(List<Integer> merIds) {
//        return dataFormat(userService.getAddUserCountGroupDate(Constants.SEARCH_DATE_LATELY_30,merId), Constants.SEARCH_DATE_LATELY_30);
        return dataFormat(userService.countAddUserGroupDateByMerIds(Constants.SEARCH_DATE_LATELY_30, merIds), Constants.SEARCH_DATE_LATELY_30);
    }

    /**
     * 订单量趋势
     * @author Mr.Zhang
     * @since 2020-05-16
     */
    @Override
    public Map<String, Object> chartOrder(List<Integer> merIds) {
        Map<String, Object> map = new HashMap<>();
//        List<StoreOrderInfo> childOrderList = storeOrderInfoService.getChildOrderGroupByDate(Constants.SEARCH_DATE_LATELY_30, Constants.NUM_TEN,merId);
////        List<StoreOrder> list = storeOrderService.getOrderGroupByDate(Constants.SEARCH_DATE_LATELY_30, Constants.NUM_TEN);
//        map.put("quality",
//                dataFormat(getChildOrderCountGroupByDate(childOrderList), Constants.SEARCH_DATE_LATELY_30)
//        );
//        map.put("price",
//                dataFormat(getChildOrderPriceGroupByDate(childOrderList), Constants.SEARCH_DATE_LATELY_30)
//        );

//        map.put("quality",
//                dataFormat(getOrderCountGroupByDate(list), Constants.SEARCH_DATE_LATELY_30)
//        );
//        map.put("price",
//                dataFormat(getOrderPriceGroupByDate(list), Constants.SEARCH_DATE_LATELY_30)
//        );
        List<StoreOrderInfo> childOrderList = storeOrderInfoService.sumChildOrderGroupByDate(Constants.SEARCH_DATE_LATELY_30, Constants.NUM_TEN, merIds);
        map.put("quality",
                dataFormat(getChildOrderCountGroupByDate(childOrderList), Constants.SEARCH_DATE_LATELY_30)
        );
        map.put("price",
                dataFormat(getChildOrderPriceGroupByDate(childOrderList), Constants.SEARCH_DATE_LATELY_30)
        );
        return map;
    }

    /**
     * 按开始结束时间查询每日新增订单数量
     * @param list List<StoreOrder> 时间范围
     * @author Mr.Zhang
     * @since 2020-05-16
     * @return HashMap<String, Object>
     */
    private Map<Object, Object> getOrderCountGroupByDate(List<StoreOrder> list) {
        Map<Object, Object> map = new HashMap<>();

        if(list.size() < 1){
            return map;
        }

        for (StoreOrder storeOrder : list) {
            map.put(storeOrder.getOrderId(), storeOrder.getId());
        }

        return map;
    }

    private Map<Object, Object> getChildOrderCountGroupByDate(List<StoreOrderInfo> list) {
        Map<Object, Object> map = new HashMap<>();

        if(list.size() < 1){
            return map;
        }

        for (StoreOrderInfo storeOrderInfo : list) {
            map.put(storeOrderInfo.getChildOrderNumber(), storeOrderInfo.getId());
        }

        return map;
    }

    /**
     * 按开始结束时间查询每日新增订单销售额
     * @param list List<StoreOrder> 时间范围
     * @author Mr.Zhang
     * @since 2020-05-16
     * @return HashMap<String, Object>
     */
    private Map<Object, Object> getOrderPriceGroupByDate(List<StoreOrder> list) {
        Map<Object, Object> map = new HashMap<>();

        if(list.size() < 1){
            return map;
        }

        for (StoreOrder storeOrder : list) {
            map.put(storeOrder.getOrderId(), storeOrder.getPayPrice());
        }

        return map;
    }

    private Map<Object, Object> getChildOrderPriceGroupByDate(List<StoreOrderInfo> list) {
        Map<Object, Object> map = new HashMap<>();
        if(list.size() < 1){
            return map;
        }
        for (StoreOrderInfo storeOrderInfo : list) {
            map.put(storeOrderInfo.getChildOrderNumber(), storeOrderInfo.getPayPrice());
        }
        return map;
    }

    /**
     * 日期和数量格式化
     * @author Mr.Zhang
     * @since 2020-05-16
     * @return Map<String, Integer>
     */
    private Map<Object, Object> dataFormat(Map<Object, Object> countGroupDate, String dateLimit){
        Map<Object, Object> map = new LinkedHashMap<>();
        List<String> listDate = DateUtil.getListDate(dateLimit);

        String[] weekList = new String[]{"周一", "周二", "周三", "周四", "周五", "周六", "周日"};

        int i = 0;
        for (String date : listDate) {
            Object count = 0;
            if(countGroupDate.containsKey(date)){
                count = countGroupDate.get(date);
            }
            String key;

            //周格式化
            switch(dateLimit){
                //格式化周
                case Constants.SEARCH_DATE_WEEK:
                case Constants.SEARCH_DATE_PRE_WEEK:
                    key = weekList[i];
                    break;
                    //格式化月
                case Constants.SEARCH_DATE_PRE_MONTH:
                case Constants.SEARCH_DATE_MONTH:
                    key = i + 1 + "";
                    break;
                    //默认显示两位日期
                default:
                    key = date.substring(5, 10);
            }
            map.put(key, count);
            i++;
        }
        return map;
    }

    /**
     * 日期和数量格式化
     * @author Mr.Zhang
     * @since 2020-05-16
     * @return Map<String, Integer>
     */
    private Map<Object, Object> dataFormatYear(Map<Object, Object> countGroupDate, String dateLimit){
        Map<Object, Object> map = new LinkedHashMap<>();
        List<Object> listDate = new ArrayList<>();
        String year = "";
        if(dateLimit.equals(Constants.SEARCH_DATE_YEAR)) {
            year = DateUtil.nowYear();
        }

        if(dateLimit.equals(Constants.SEARCH_DATE_PRE_YEAR)) {
            year = DateUtil.lastYear();
        }

        //处理年
        //12个月份数据
        for (int i = 1; i <= 12; i++){
            String month = i + "";
            if(i < 10){
                month = "0" + i;
            }
            listDate.add(year + "-" + month);
        }

        String[] monthList = new String[]{"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月" , "十一月", "十二月" };

        int i = 0;
        for (Object date : listDate) {
            Object count = 0;
            if(countGroupDate.containsKey(date)){
                count = countGroupDate.get(date);
            }
            map.put(monthList[i], count);
            i++;
        }
        return map;
    }

    /**
     * 用户购买统计
     * @author Mr.Zhang
     * @since 2020-05-16
     */
    @Override
    public Map<String, Integer> chartUserBuy(List<Integer> merIds) {
        Map<String, Integer> map = new HashMap<>();
//        //未消费用户
//        map.put("zero", userService.getCountByPayCount(Constants.NUM_ZERO, Constants.NUM_ZERO,merId));
//
//        //消费一次用户
//        map.put("one", userService.getCountByPayCount(Constants.NUM_ONE, Constants.NUM_ONE,merId));
//
//        //留存客户
//        map.put("history", userService.getCountByPayCount(Constants.NUM_TWO, Constants.NUM_THREE,merId));
//
//        //回流客户
//        map.put("back", userService.getCountByPayCount(Constants.NUM_ONE, Constants.EXPORT_MAX_LIMIT,merId));

        //未消费用户
        map.put("zero", userService.countPayUserByMerIds(Constants.NUM_ZERO, Constants.NUM_ZERO, merIds));

        //消费一次用户
        map.put("one", userService.countPayUserByMerIds(Constants.NUM_ONE, Constants.NUM_ONE, merIds));

        //留存客户
        map.put("history", userService.countPayUserByMerIds(Constants.NUM_TWO, Constants.NUM_THREE, merIds));

        //回流客户
        map.put("back", userService.countPayUserByMerIds(Constants.NUM_ONE, Constants.EXPORT_MAX_LIMIT, merIds));

        return map;
    }

    /**
     * 周订单量趋势
     * @author Mr.Zhang
     * @since 2020-05-16
     * @return Map<String, Object>
     */
    @Override
    public Map<String, Object> chartOrderInWeek(List<Integer> merIds) {
        return returnOrderDate(Constants.SEARCH_DATE_WEEK, Constants.SEARCH_DATE_PRE_WEEK, Constants.NUM_TEN, merIds);
    }

    /**
     * 月订单量趋势
     * @author Mr.Zhang
     * @since 2020-05-16
     * @return Map<String, Object>
     */
    @Override
    public Map<String, Object> chartOrderInMonth(List<Integer> merIds) {
        return returnOrderDate(Constants.SEARCH_DATE_MONTH, Constants.SEARCH_DATE_PRE_MONTH, Constants.NUM_TEN, merIds);
    }

    /**
     * 年订单量趋势
     * @author Mr.Zhang
     * @since 2020-05-16
     * @return Map<String, Object>
     */
    @Override
    public Map<String, Object> chartOrderInYear(List<Integer> merIds) {
        Map<String, Object> map = new HashMap<>();

        //查询本年订单量
//        List<StoreOrderInfo> storeOrderInfoList = storeOrderInfoService.getChildOrderGroupByDate(Constants.SEARCH_DATE_YEAR, Constants.NUM_SEVEN,merId);
//        List<StoreOrder> list = storeOrderService.getOrderGroupByDate(Constants.SEARCH_DATE_YEAR, Constants.NUM_SEVEN);
        List<StoreOrderInfo> storeOrderInfoList = storeOrderInfoService.sumChildOrderGroupByDate(Constants.SEARCH_DATE_YEAR, Constants.NUM_SEVEN,merIds);

        map.put("quality",
                dataFormatYear(getChildOrderCountGroupByDate(storeOrderInfoList), Constants.SEARCH_DATE_YEAR)
        );
        map.put("price",
                dataFormatYear(getChildOrderCountGroupByDate(storeOrderInfoList), Constants.SEARCH_DATE_YEAR)
        );

        //查询上年订单量
//        List<StoreOrderInfo> preStoreOrderInfoList = storeOrderInfoService.getChildOrderGroupByDate(Constants.SEARCH_DATE_PRE_YEAR, Constants.NUM_SEVEN,merId);
//        List<StoreOrder> preList = storeOrderService.getOrderGroupByDate(Constants.SEARCH_DATE_PRE_YEAR, Constants.NUM_SEVEN);
        List<StoreOrderInfo> preStoreOrderInfoList = storeOrderInfoService.sumChildOrderGroupByDate(Constants.SEARCH_DATE_PRE_YEAR, Constants.NUM_SEVEN,merIds);

        map.put("preQuality",
                dataFormatYear(getChildOrderCountGroupByDate(preStoreOrderInfoList), Constants.SEARCH_DATE_PRE_YEAR)
        );
        map.put("prePrice",
                dataFormatYear(getChildOrderCountGroupByDate(preStoreOrderInfoList), Constants.SEARCH_DATE_PRE_YEAR)
        );

        return map;
    }

    @Override
    public List<OrderTodayResponse> orderToday(Integer merId) {
        List<OrderTodayResponse> list = new ArrayList<>();
        //总订单数量
        QueryWrapper<StoreOrderInfo> allQueryWrapper = new QueryWrapper<>();
        queryCondition(merId, allQueryWrapper);
        allQueryWrapper.select("count(DISTINCT order_id) as order_id,count(1) as id");
        StoreOrderInfo allStoreOrderInfo = storeOrderInfoService.getOne(allQueryWrapper);
        //自建订单
        QueryWrapper<StoreOrderInfo> selfQueryWrapper = new QueryWrapper<>();
        queryCondition(merId, selfQueryWrapper);
//        selfQueryWrapper.like("info","\"isEurope\":1,");
        selfQueryWrapper.lambda().eq(StoreOrderInfo::getIsEurope, 1);
        //数量 / 销售额
        selfQueryWrapper.select("count(1) as id ,ifnull(sum(pay_price + deduction_price),0) pay_price");
        StoreOrderInfo selfStoreOrderInfo = storeOrderInfoService.getOne(selfQueryWrapper);
        //收入
        selfQueryWrapper.ne("status",-2);
        StoreOrderInfo incomeStoreOrderInfo = storeOrderInfoService.getOne(selfQueryWrapper);
        //云仓订单
        QueryWrapper<StoreOrderInfo> cloudQueryWrapper = new QueryWrapper<>();
        queryCondition(merId, cloudQueryWrapper);
//        cloudQueryWrapper.notLike("info","\"isEurope\":1,");
        cloudQueryWrapper.lambda().and(i -> i.isNull(StoreOrderInfo::getIsEurope).or().ne(StoreOrderInfo::getIsEurope, 1));
        // 数量 / 销售额
        cloudQueryWrapper.select("count(1) as id ,ifnull(sum(pay_price + deduction_price),0) pay_price");
        StoreOrderInfo cloudStoreOrderInfo = storeOrderInfoService.getOne(cloudQueryWrapper);
        //收入
        QueryWrapper<StoreOrderInfo> inCloudQueryWrapper = new QueryWrapper<>();
        queryCondition(merId, inCloudQueryWrapper);
//        inCloudQueryWrapper.notLike("info","\"isEurope\":1,").ne("status",-2);
        inCloudQueryWrapper.lambda()
                .and(i -> i.isNull(StoreOrderInfo::getIsEurope).or().ne(StoreOrderInfo::getIsEurope, 1))
                .ne(StoreOrderInfo::getStatus,-2);
        List<StoreOrderInfo> storeOrderInfoList = storeOrderInfoService.list(inCloudQueryWrapper);
        BigDecimal amountFrozen = BigDecimal.ZERO;
        for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) {
            StoreCartResponse storeCartResponse = JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class);
            StoreProductAttrValue attrInfo = storeCartResponse.getProductInfo().getAttrInfo();
            BigDecimal subtract = attrInfo.getPrice().subtract(attrInfo.getCost());
            if(subtract.compareTo(BigDecimal.ZERO)>0){
                amountFrozen = amountFrozen.add(subtract);
            }
        }
        list.add(new OrderTodayResponse().setType(1).setTodayData(allStoreOrderInfo.getOrderId()).setSelfData(selfStoreOrderInfo.getId()).setCloudData(cloudStoreOrderInfo.getId()));
        list.add(new OrderTodayResponse().setType(2).setTodayData(selfStoreOrderInfo.getPayPrice().add(cloudStoreOrderInfo.getPayPrice())).setSelfData(selfStoreOrderInfo.getPayPrice()).setCloudData(cloudStoreOrderInfo.getPayPrice()));
        list.add(new OrderTodayResponse().setType(3).setTodayData(incomeStoreOrderInfo.getPayPrice().add(amountFrozen)).setSelfData(incomeStoreOrderInfo.getPayPrice()).setCloudData(amountFrozen));
        return list;
    }

    @Override
    public CustomerManagementResponse customerManagement(Integer merId) {
        CustomerManagementResponse response = new CustomerManagementResponse();
        //本月数量
        Integer mocth = userService.getAddUserCountByDate(Constants.SEARCH_DATE_MONTH,Collections.singletonList(merId));
        //总数量
        Integer all = userService.getAddUserCountByDate(null,Collections.singletonList(merId));
        //本月交易
        dateLimitUtilVo dateLimit = DateUtil.getDateLimit(Constants.SEARCH_DATE_MONTH);
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("count(DISTINCT uid) as uid").ne("status",0).ne("status",5).eq("mer_id",merId);
        queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime());
        StoreOrder storeOrder = storeOrderService.getOne(queryWrapper);
        response.setMonth(mocth);
        response.setAll(all);
        response.setTrade(storeOrder.getUid());
        return response;
    }

    @Override
    public SupplierSalesResponse supplierSales(Integer merId) {
        SupplierSalesResponse response = new SupplierSalesResponse();
        SupplierInfo supplierInfo = channelMerchantService.getSupplierInfo(merId);

        QueryWrapper<PurchaseGoods> queryWrapper = new QueryWrapper<>();
        boolean flag = Objects.nonNull(supplierInfo.getCurrency()) && !supplierInfo.getCurrency().equals(CurrencyEnum.CN);
        if(flag){
            queryWrapper.select("goods_price/exchange_rate goods_price,create_time");
        }else {
            queryWrapper.select("goods_price,create_time");
        }
        queryWrapper.eq("channel_type",supplierInfo.getIsEurope())
                .ne("status",0).ne("status",5)
                .eq("push_status",1);
        List<PurchaseGoods> goodsList = purchaseGoodsService.list(queryWrapper);
//        List<PurchaseGoods> goodsList = purchaseGoodsService.list(Wrappers.<PurchaseGoods>lambdaQuery()
//                .eq(PurchaseGoods::getChannelType, supplierInfo.getSupplierUnificationEnum().getType())
//                .eq(PurchaseGoods::getPushStatus, 1)
//                .ne(PurchaseGoods::getStatus, 0)
//                .ne(PurchaseGoods::getStatus, 5));
        BigDecimal count = goodsList.stream().map(PurchaseGoods::getGoodsPrice).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal todayCount = goodsList.stream().filter(e -> e.getCreateTime().compareTo(DateUtil.initDateByDay()) > -1).map(PurchaseGoods::getGoodsPrice).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
        response.setCount(count.setScale(2, RoundingMode.UP));
        response.setTodayCount(todayCount.setScale(2, RoundingMode.UP));
        return response;
    }

    @Override
    public List<SupplierRankingResponse> brandRanking(String dateLimit, Integer merId) {
        SupplierInfo supplierInfo = channelMerchantService.getSupplierInfo(merId);
        boolean flag = Objects.nonNull(supplierInfo.getCurrency()) && !supplierInfo.getCurrency().equals(CurrencyEnum.CN);
        dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(dateLimit);
        QueryWrapper<PurchaseGoods> queryWrapper = new QueryWrapper<>();
        if(flag){
            queryWrapper.select(" sum(goods_price/exchange_rate) goods_price,goods_brand,count(goods_brand) goods_number ");
        }else {
            queryWrapper.select(" sum(goods_price) goods_price,goods_brand,count(goods_brand) goods_number ");
        }
        queryWrapper.eq("channel_type",supplierInfo.getIsEurope())
                .ne("status",0)
                .eq("push_status",1);
        queryWrapper.between("create_time", dateLimitUtilVo.getStartTime(), dateLimitUtilVo.getEndTime());
        queryWrapper.groupBy("goods_brand").orderByDesc("goods_number");
        List<PurchaseGoods> goodsList = purchaseGoodsService.list(queryWrapper);
        List<SupplierRankingResponse> list = new ArrayList<>();
        for (PurchaseGoods goods : goodsList) {
            SupplierRankingResponse response = new SupplierRankingResponse();
            response.setBrandName(goods.getGoodsBrand());
            response.setCount(Integer.parseInt(goods.getGoodsNumber()));
            response.setAmount(goods.getGoodsPrice().setScale(2, RoundingMode.UP));
            list.add(response);
        }
        return list;
    }

    @Override
    public List<SupplierRankingResponse> productRanking(String dateLimit, Integer merId) {
        SupplierInfo supplierInfo = channelMerchantService.getSupplierInfo(merId);
        boolean flag = Objects.nonNull(supplierInfo.getCurrency()) && !supplierInfo.getCurrency().equals(CurrencyEnum.CN);
        dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(dateLimit);
        QueryWrapper<PurchaseGoods> queryWrapper = new QueryWrapper<>();
        if(flag){
            queryWrapper.select(" sum(goods_price/exchange_rate) goods_price,goods_name,good_keyword,goods_brand,count(id) goods_number ");
        }else {
            queryWrapper.select(" sum(goods_price) goods_price,goods_name,good_keyword,goods_brand,count(id) goods_number ");
        }
        queryWrapper.eq("channel_type",supplierInfo.getIsEurope())
                .ne("status",0)
                .eq("push_status",1);
        queryWrapper.between("create_time", dateLimitUtilVo.getStartTime(), dateLimitUtilVo.getEndTime());
        queryWrapper.groupBy("goods_id").orderByDesc("goods_number");
        List<PurchaseGoods> goodsList = purchaseGoodsService.list(queryWrapper);
        List<SupplierRankingResponse> list = new ArrayList<>();
        for (PurchaseGoods goods : goodsList) {
            SupplierRankingResponse response = new SupplierRankingResponse();
            response.setBrandName(goods.getGoodsBrand());
            response.setCount(Integer.parseInt(goods.getGoodsNumber()));
            response.setAmount(goods.getGoodsPrice().setScale(2, RoundingMode.UP));
            response.setProductName(goods.getGoodsName());
            response.setKeyword(goods.getGoodKeyword());
            list.add(response);
        }
        return list;
    }

    public void queryCondition(Integer merId, QueryWrapper<StoreOrderInfo> queryWrapper) {
        dateLimitUtilVo dateLimit = DateUtil.getDateLimit(Constants.SEARCH_DATE_DAY);
        queryWrapper.ne("status",0).ne("status",5)
                .inSql("order_id","select id from eb_store_order where mer_id = " + merId);
        queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime());
    }

    /**
     * 组装订单统计返回数据
     * @author Mr.Zhang
     * @since 2020-05-16
     * @return Map<String, Object>
     */
    private Map<String, Object> returnOrderDate(String dateLimit, String preDateLimit, int leftTime,List<Integer> merIds){
        Map<String, Object> map = new HashMap<>();

        //查询本周周订单量
//        List<StoreOrderInfo> storeOrderInfoList = storeOrderInfoService.getChildOrderGroupByDate(dateLimit, leftTime,merId);
//        List<StoreOrder> list = storeOrderService.getOrderGroupByDate(dateLimit, leftTime);
        List<StoreOrderInfo> storeOrderInfoList = storeOrderInfoService.sumChildOrderGroupByDate(dateLimit, leftTime,merIds);

        map.put("quality",
                dataFormat(getChildOrderCountGroupByDate(storeOrderInfoList), dateLimit)
        );
        map.put("price",
                dataFormat(getChildOrderCountGroupByDate(storeOrderInfoList), dateLimit)
        );

        //查询上周周订单量
//        List<StoreOrderInfo> preStoreOrderInfoList = storeOrderInfoService.getChildOrderGroupByDate(dateLimit, leftTime,merId);
//        List<StoreOrder> preList = storeOrderService.getOrderGroupByDate(preDateLimit, leftTime);
        List<StoreOrderInfo> preStoreOrderInfoList = storeOrderInfoService.sumChildOrderGroupByDate(dateLimit, leftTime,merIds);

        map.put("preQuality",
                dataFormat(getChildOrderCountGroupByDate(preStoreOrderInfoList), preDateLimit)
        );
        map.put("prePrice",
                dataFormat(getChildOrderCountGroupByDate(preStoreOrderInfoList), preDateLimit)
        );

        return map;
    }

}
